#include "BreakPointService.h"
#include <iostream>
#include "BreakPointFile.h"
#include "BreakPointDecorator.h"


BreakPointService::BreakPointService()
: status(END)
, breakPoint(new BreakPointDecorator(new BreakPointFile("./seqNo.bin")))
{
}
BreakPointService::~BreakPointService()
{
    if(breakPoint != nullptr){
        delete breakPoint;
        breakPoint = nullptr;
    }
}

std::ostream &  BreakPointService::logStatus(std::ostream & out){
       out << "\tstatus :"  << status << " [0-end,1-inited,2-connected,3-logined,4-disconnected]" << std::endl;
       return out;
}

int BreakPointService::start(){
    std::cout << "BreakPointService::start " << std::endl;

    if(status == END){
        //first loadFromFile, then set to mem
        std::cout << "BreakPointService::loadFromFile, breakPoint:" 
            << breakPoint->get() << std::endl;

        status = INITED;
        logStatus(std::cout);
        return 0;
    }
    return -1;
}
int BreakPointService::stop(){
    std::cout << "BreakPointService::stop to: " << breakPoint->get() << std::endl;
    if(status != END ){
        std::cout << "BreakPointService::saveToFile " << std::endl;
        breakPoint->set(breakPoint->get());//save the mem seqNo to file
        status = END;
        std::cout << "BreakPointService:: end" << std::endl;
        logStatus(std::cout);
        return 0;
    }
    else{
        std::cout << "status check error: END status already" << std::endl;
        logStatus(std::cout);
        return -1;
    }
}

int BreakPointService::connected(){
    std::cout << "BreakPointService::connected " << std::endl;
    if(status == INITED){
        status = CONNECTED;
        return sendMessage("login-req");
    }
    else{
        std::cout << "current status error:" << std::endl;
        logStatus(std::cout);
        return -1;
    }
}
int BreakPointService::disconnected(){
    if(status == CONNECTED || status == LOGINED){
        status = DISCONNECTED;
        std::cout << "BreakPointService::disconnected " << std::endl;
        logStatus(std::cout);
        return 0;
    }
    else{
        std::cout << "current status error:" << std::endl;
        logStatus(std::cout);
        return -1;
    }
}


int BreakPointService::receivedLoginResp(const char * msg){
    std::cout << "BreakPointService::receive :[" << msg << "]" 
        << "\n\tswitch to [login] status if response ok" 
        << std::endl;

    if(status == CONNECTED){
        status = LOGINED;
        logStatus(std::cout);
        return 0;
    } 
    else{
        std::cout << "status error: need connected status" << std::endl;
        logStatus(std::cout);
        return -1;
    }
}

int BreakPointService::receivedBreakPointResp(const char * msg){
    std::cout << "BreakPointService::receive :[" << msg << "]" << std::endl;
    if(status == LOGINED){
        return 0;
    }
    std::cout << "Error: need LOGINED status " << std::endl;
    return -1;
}

int BreakPointService::receivedNormalResp(const char * msg){
    std::cout << "BreakPointService::receive :[" << msg << "]" << std::endl;
    if(status == LOGINED){
        breakPoint->add(1); //fake action
        return 0;
    }
    else{
        std::cout << "Error: need LOGINED status " << std::endl;
        return -1;
    }
}

int BreakPointService::sendMessage(const char * msg){
    if(status == LOGINED || status == CONNECTED){
        std::cout << "BreakPointService::send : [" << msg << "] " << std::endl;
        logStatus(std::cout);
        return 0;
    }
    std::cout << "need status : LOGINED or CONNECTED" << std::endl;
    logStatus(std::cout);
    return -1;
}

int BreakPointService::timeout(){
    std::cout << "BreakPointService::timeout "
        <<"-> query the data [" <<  breakPoint->get()+1 <<  ", MAX)" << std::endl;

    if(status == LOGINED){
        if(0 == sendMessage("breakPoint-req")){
            std::cout << "BreakPointService::saveToFile " << std::endl;
            breakPoint->set(breakPoint->get());
            return 0;
        }
        else{
            std::cout << "send message failed" << std::endl;
            return -1;
        }
    }
    else{
        std::cout << "need logined status:" << std::endl;
        logStatus(std::cout);
        return -1;
    }
}
